package me.zhyd.justauth;

import me.zhyd.justauth.cache.AuthStateRedisCache;
import me.zhyd.justauth.ext.AuthMyGitlabRequest;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 实战演示如何使用JustAuth实现第三方登录
 *
 * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
 * @version 1.0.0
 * @since 1.0.0
 */
@RestController
@RequestMapping("/oauth")
public class JustAuthController {

    /**
     * 注入自定义的缓存实现类
     */
    @Autowired
    private AuthStateRedisCache stateRedisCache;

    /**
     * 获取授权链接并跳转到第三方授权页面
     *
     * @param source   第三方授权平台
     * @param response response
     * @throws IOException response可能存在的异常
     */
    @RequestMapping("/render/{source}")
    public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = getAuthRequest(source);
        String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
        response.sendRedirect(authorizeUrl);
    }

    /**
     * 用户在确认第三方平台授权（登录）后， 第三方平台会重定向到该地址，并携带code、state等参数
     *
     * @param source   第三方授权平台
     * @param callback 第三方回调时的入参
     * @return 第三方平台的用户信息
     */
    @RequestMapping("/callback/{source}")
    public Object login(@PathVariable("source") String source, AuthCallback callback) {
        AuthRequest authRequest = getAuthRequest(source);
        return authRequest.login(callback);
    }

    /**
     * 获取授权Request
     *
     * @param source 第三方授权平台
     * @return AuthRequest
     */
    private AuthRequest getAuthRequest(String source) {
        AuthRequest authRequest = null;
        switch (source) {
            case "gitee":
                authRequest = new AuthGiteeRequest(AuthConfig.builder()
                        .clientId("4c504cd2e1b1dbaba8dc1187d8070adf679acab17b2bc9cf6dfa76b9ae06aadc")
                        .clientSecret("fa5857175723475e4675e36af9eafde338545c1a0dfa49d1e0cc78f9c3ce5ebe")
                        .redirectUri("http://localhost:8080/oauth/callback/gitee")
                        .build(), stateRedisCache);
                break;
            case "mygitlab":
                authRequest = new AuthMyGitlabRequest(AuthConfig.builder()
                        .clientId("6ff1e2ccc356a4c193b663a2fbd4be34807e97a630e6e225d8d980ee9406d4a1")
                        .clientSecret("d935d24579e689c7cc8b41407a1b7886e45e8da3cd40fb2694bc8a00c0430c4e")
                        .redirectUri("http://localhost:8080/oauth/callback/mygitlab")
                        .build());
                break;
            default:
                break;
        }
        if (null == authRequest) {
            throw new AuthException("未获取到有效的Auth配置");
        }
        return authRequest;
    }

}
